package com.luoran.system.utils;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class RowSameValueMergeStrategy extends AbstractMergeStrategy {



    /**
     * 需要合并的列位置索引
     */
    private int[] mergeColumnIndexArray;

    // 记录mergeColumnIndexArray中每一列的上一行的值和索引
    private Map<Integer, ValueAndIndex> lastValueMap;

    /**
     * 用来记录上一次的值和索引，用于判断是否需要合并
     */
    @Data
    @AllArgsConstructor
    static class ValueAndIndex {
        private String value;
        private int index;
    }


    public RowSameValueMergeStrategy(int[] mergeColumnIndexArray) {
        this.mergeColumnIndexArray = mergeColumnIndexArray;
        int initialCapacity = (int) Math.ceil(mergeColumnIndexArray.length / 0.75);
        lastValueMap = new HashMap<>(initialCapacity);
    }

//    sheet：代表一个 Excel 工作表，通过这个对象可以对工作表进行各种操作，如获取行、列、设置单元格格式等。
//    cell：表示一个具体的单元格，可能用于确定要进行合并的起始单元格。
//    head：不太明确具体用途，可能与表头信息相关，用于在合并操作中根据特定的表头规则进行处理。
//    relativeRowIndex：一个整数，表示相对行索引，可能用于确定合并的范围或者在特定行的基础上进行操作。
    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
        if (head == null) {
            return;
        }
        if (mergeColumnIndexArray == null) {
            return;
        }
        for (int i = 0; i < mergeColumnIndexArray.length; i++) {
            int mergeIndex = mergeColumnIndexArray[i];
            if (head.getColumnIndex() == mergeIndex) {
                String value = cell.getStringCellValue();
                int rowIndex = cell.getRowIndex();
                if (lastValueMap.get(mergeIndex) == null) {
                    lastValueMap.put(mergeIndex, new ValueAndIndex(value, rowIndex));
                }
                ValueAndIndex valueAndIndex = lastValueMap.get(mergeIndex);
                Integer lastRowIndex = valueAndIndex.getIndex();
                String lastValue = valueAndIndex.getValue();
                // 合并值相同的相邻单元格，当前单元格合并上一个单元格
                if (Objects.equals(value, lastValue) && lastRowIndex != rowIndex) {
                    sheet.addMergedRegionUnsafe(new CellRangeAddress(
                            lastRowIndex, // 起始行
                            rowIndex,     // 结束行
                            mergeIndex,   // 起始列
                            mergeIndex   // 结束列
                    ));

                    // 设置合并后的单元格样式为垂直居中
                    Workbook workbook = sheet.getWorkbook();
                    CellStyle cellStyle = workbook.createCellStyle();
                    cellStyle.setAlignment(HorizontalAlignment.CENTER);
                    cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
                    for (int r = lastRowIndex; r <= rowIndex; r++) {
                        Cell mergedCell = sheet.getRow(r).getCell(mergeIndex);
                        if (mergedCell!= null) {
                            mergedCell.setCellStyle(cellStyle);
                        }
                    }

                }
                lastValueMap.put(mergeIndex, new ValueAndIndex(value, rowIndex));
            }
        }
    }

}
